Dynamic Web Applications
Dynamic Web Applications are web applications whose content, elements, attributes, layout, or behavior can change dynamically based on user actions, server responses, JavaScript execution, AJAX requests, API responses, session information, database data, or other runtime conditions.
Testing dynamic web applications with Selenium requires more than simply locating elements and performing clicks. Automation scripts must be designed to handle changing element attributes, dynamically generated elements, asynchronous content, changing page states, popups, AJAX requests, tables, dropdowns, frames, windows, and other runtime changes.
Dynamic web application handling is an important part of Selenium automation because modern websites frequently use JavaScript frameworks and asynchronous communication to update portions of a page without performing a complete page refresh.
Course Resource: Selenium Training | Register for Course Demo
1. What is a Dynamic Web Application?
A dynamic web application is a website or web-based system where the displayed content or behavior can change while the application is running. The change may occur because of user interaction, server-side processing, database updates, JavaScript, API calls, AJAX requests, or application state.
Unlike a completely static page, a dynamic application can generate different elements or values at different times.
Examples include:
- Online shopping applications.
- Banking applications.
- Social media platforms.
- Travel booking websites.
- Food delivery applications.
- Online dashboards.
- CRM applications.
- Job portals.
- Real-time reporting systems.
2. Static vs Dynamic Web Applications
| Static Web Application | Dynamic Web Application |
| Content changes rarely. | Content can change frequently. |
| Elements generally have predictable properties. | Element properties may change at runtime. |
| Simple automation is often sufficient. | Synchronization and dynamic locators are often required. |
| Page structure is relatively stable. | DOM structure may change dynamically. |
| Less JavaScript interaction. | Heavy JavaScript and AJAX usage is common. |
| Simple waits may be sufficient. | Explicit or condition-based waits are frequently required. |
3. Why Dynamic Applications are Challenging for Selenium
Selenium interacts with the browser and DOM. When an application changes its DOM dynamically, an automation script that assumes a fixed structure may fail.
Common challenges include:
- Dynamic IDs.
- Changing class names.
- Elements appearing after a delay.
- Elements disappearing after an action.
- AJAX-based content updates.
- Dynamic tables.
- Changing dropdown options.
- Dynamic pagination.
- Loading spinners.
- Popups and overlays.
- Stale elements.
- Elements that are present but not clickable.
- Changing text values.
- Lazy-loaded content.
- Multiple windows and tabs.
- Dynamic frames and iframes.
4. Dynamic Web Application Flow
User Action
|
v
Browser Event
|
v
JavaScript / Frontend Logic
|
v
API / AJAX Request
|
v
Server / Database
|
v
Response
|
v
DOM Updated
|
v
New or Modified Web Element
|
v
Selenium Interaction
Selenium automation must synchronize with the application between the browser action and the final DOM state.
5. Dynamic Elements
A dynamic element is an element whose properties or position can change during different executions of the application.
For example, an element may have an ID such as:
<input id="user_45892" type="text">
During another execution, the ID might become:
<input id="user_92741" type="text">
A locator that depends completely on the changing numeric portion may become unreliable.
6. Handling Dynamic IDs
When an ID contains a stable portion and a changing portion, XPath functions such as starts-with(), contains(), or other stable attributes can be used.
Using starts-with()
driver.findElement(
By.xpath("//input[starts-with(@id,'user_')]")
).sendKeys("John");
Using contains()
driver.findElement(
By.xpath("//input[contains(@id,'user_')]")
).sendKeys("John");
The important principle is to identify the stable part of the element rather than depending on the entire changing value.
7. Handling Dynamic Class Names
Modern frontend frameworks may generate classes dynamically. For example:
<button class="btn-primary-78291">Login</button>
Instead of depending on the complete class name, a stable portion can sometimes be used.
driver.findElement(
By.xpath("//button[contains(@class,'btn-primary')]")
).click();
However, class-based locators should be used carefully when classes are generated automatically or are intended only for styling.
8. Stable Locators for Dynamic Applications
The first strategy for dynamic applications should be to identify stable attributes.
Useful locator attributes include:
- Unique ID.
- Stable name.
- Stable data attributes.
- Accessible labels.
- Stable ARIA attributes.
- Meaningful custom attributes.
- Reliable CSS selectors.
- Relative XPath expressions.
For example:
<button data-testid="login-button">Login</button>
Selenium can locate it using:
driver.findElement(
By.cssSelector("[data-testid='login-button']")
).click();
9. Using data-* Attributes
Modern web applications often provide custom data-* attributes specifically for testing or application behavior.
<button data-testid="submit-login">Login</button>
CSS:
driver.findElement(
By.cssSelector("[data-testid='submit-login']")
).click();
XPath:
driver.findElement(
By.xpath("//button[@data-testid='submit-login']")
).click();
Stable test attributes can make automation scripts more maintainable.
10. Dynamic XPath
Dynamic XPath means creating an XPath expression that can identify an element even when some of its properties change.
Common XPath functions
| Function | Purpose | Example |
| contains() | Matches a partial value. | //button[contains(@id,'login')] |
| starts-with() | Matches the beginning of a value. | //input[starts-with(@id,'user')] |
| text() | Matches visible text. | //button[text()='Login'] |
| normalize-space() | Handles unnecessary whitespace. | //button[normalize-space()='Login'] |
| and | Combines conditions. | //input[@type='text' and @name='user'] |
| or | Matches either condition. | //button[@id='login' or @name='login'] |
11. Dynamic XPath with contains()
driver.findElement(
By.xpath("//input[contains(@id,'username')]")
).sendKeys("admin");
This can be useful when the ID contains a stable keyword but additional characters are generated dynamically.
12. Dynamic XPath with starts-with()
driver.findElement(
By.xpath("//input[starts-with(@id,'user')]")
).sendKeys("admin");
This approach is useful when the beginning of an attribute remains stable while the remaining portion changes.
13. Dynamic XPath Using Multiple Attributes
If one attribute is not reliable, multiple stable attributes can be combined.
driver.findElement(
By.xpath("//input[@type='text' and contains(@placeholder,'Username')]")
).sendKeys("admin");
Combining attributes can reduce the possibility of selecting an incorrect element.
14. Handling Dynamic Text
Text displayed by an application can also change dynamically.
For example:
Welcome, John
Welcome, David
Welcome, Robert
Instead of matching the complete text, a stable part can be used.
driver.findElement(
By.xpath("//*[contains(text(),'Welcome')]")
);
For complex applications, it is generally better to use a stable attribute when one is available.
15. Handling AJAX Applications
AJAX allows a web application to communicate with the server without requiring a complete page refresh.
For example, when a user searches for a product, the application may send an asynchronous request and update only the search-results section.
User enters search
|
v
AJAX request
|
v
Server processes request
|
v
Response returned
|
v
DOM updated
|
v
Search results displayed
Selenium must wait for the required condition instead of assuming that the content is immediately available.
16. Explicit Wait for Dynamic Elements
Explicit waits are one of the most important techniques for dynamic web applications.
WebDriverWait wait = new WebDriverWait(
driver,
Duration.ofSeconds(10)
);
WebElement loginButton = wait.until(
ExpectedConditions.elementToBeClickable(
By.id("loginButton")
)
);
loginButton.click();
The test waits until the specified condition is satisfied or the timeout is reached.
17. Common Explicit Wait Conditions
| Condition | Use |
| visibilityOfElementLocated() | Wait until an element is visible. |
| elementToBeClickable() | Wait until an element can be clicked. |
| presenceOfElementLocated() | Wait until an element is present in the DOM. |
| invisibilityOfElementLocated() | Wait until an element becomes invisible. |
| textToBePresentInElementLocated() | Wait for expected text. |
| urlContains() | Wait until the URL contains expected text. |
| titleContains() | Wait until the page title contains expected text. |
| frameToBeAvailableAndSwitchToIt() | Wait for a frame and switch into it. |
18. Waiting for Element Visibility
WebDriverWait wait = new WebDriverWait(
driver,
Duration.ofSeconds(10)
);
WebElement username = wait.until(
ExpectedConditions.visibilityOfElementLocated(
By.id("username")
)
);
username.sendKeys("admin");
19. Waiting for Element to be Clickable
WebElement button = wait.until(
ExpectedConditions.elementToBeClickable(
By.id("submit")
)
);
button.click();
This is useful when a button exists in the DOM but is temporarily disabled, covered, or otherwise not ready for interaction.
20. Handling Loading Spinners
Modern applications often display loading indicators while data is being fetched.
WebDriverWait wait = new WebDriverWait(
driver,
Duration.ofSeconds(15)
);
wait.until(
ExpectedConditions.invisibilityOfElementLocated(
By.cssSelector(".loading-spinner")
)
);
The test can continue after the loading indicator disappears.
21. Handling Dynamic Tables
Dynamic tables are common in dashboards, admin panels, banking applications, and e-commerce applications.
Example table:
<table id="users">
<tr>
<td>John</td>
<td>Admin</td>
</tr>
<tr>
<td>David</td>
<td>Manager</td>
</tr>
</table>
Searching for a specific row can be done using XPath.
WebElement row = driver.findElement(
By.xpath("//table[@id='users']//tr[td[text()='John']]")
);
22. Finding a Button Inside a Dynamic Table Row
Suppose every row has an Edit button.
WebElement editButton = driver.findElement(
By.xpath(
"//tr[td[text()='John']]//button[contains(.,'Edit')]"
)
);
editButton.click();
This technique associates the action with a specific row instead of relying on a fixed row number.
23. Handling Dynamic Dropdowns
Some dropdowns load their options dynamically after the user clicks or types.
driver.findElement(By.id("country")).click();
WebDriverWait wait = new WebDriverWait(
driver,
Duration.ofSeconds(10)
);
WebElement India = wait.until(
ExpectedConditions.elementToBeClickable(
By.xpath("//li[normalize-space()='India']")
)
);
India.click();
24. Auto-Suggestion Handling
Search boxes frequently display dynamically generated suggestions.
driver.findElement(By.id("search"))
.sendKeys("Selenium");
WebDriverWait wait = new WebDriverWait(
driver,
Duration.ofSeconds(10)
);
WebElement suggestion = wait.until(
ExpectedConditions.visibilityOfElementLocated(
By.xpath("//li[contains(.,'Selenium WebDriver')]")
)
);
suggestion.click();
25. Handling Dynamic Pagination
Pagination controls can change depending on the number of records.
WebDriverWait wait = new WebDriverWait(
driver,
Duration.ofSeconds(10)
);
WebElement nextButton = wait.until(
ExpectedConditions.elementToBeClickable(
By.xpath("//button[contains(.,'Next')]")
)
);
nextButton.click();
For dynamic pagination, the automation should verify whether a next page exists before attempting to click it.
26. Handling Infinite Scroll
Some applications load additional content when the user scrolls toward the bottom of the page.
JavascriptExecutor js =
(JavascriptExecutor) driver;
js.executeScript(
"window.scrollTo(0, document.body.scrollHeight);"
);
The test may then wait for additional content to appear.
WebDriverWait wait = new WebDriverWait(
driver,
Duration.ofSeconds(10)
);
wait.until(
ExpectedConditions.visibilityOfElementLocated(
By.cssSelector(".new-content")
)
);
27. Lazy-Loaded Elements
Lazy loading means that content is loaded only when it becomes necessary, often when the user scrolls near it.
Examples include:
- Images.
- Product cards.
- Videos.
- Articles.
- Dashboard widgets.
Selenium scripts may need to scroll to the required region and wait for the element to become visible.
28. Handling StaleElementReferenceException
StaleElementReferenceException can occur when Selenium holds a reference to an element that has been removed or replaced in the DOM.
For example:
WebElement element =
driver.findElement(By.id("username"));
driver.navigate().refresh();
element.sendKeys("admin");
The original element reference may no longer represent the current DOM element.
A common solution is to locate the element again after the DOM update.
driver.navigate().refresh();
WebElement element =
driver.findElement(By.id("username"));
element.sendKeys("admin");
29. Retrying a Stale Element
For applications that frequently replace elements, a controlled retry strategy can be used.
for (int i = 0; i < 3; i++) {
try {
driver.findElement(By.id("username"))
.sendKeys("admin");
break;
} catch (StaleElementReferenceException e) {
// Retry locating the element.
}
}
Retries should be limited and used for known transient conditions rather than hiding genuine application failures.
30. Handling Elements That Appear After JavaScript Execution
Some elements are created only after JavaScript executes.
WebDriverWait wait = new WebDriverWait(
driver,
Duration.ofSeconds(10)
);
WebElement dynamicElement = wait.until(
ExpectedConditions.presenceOfElementLocated(
By.cssSelector(".dynamic-element")
)
);
Waiting for presence is useful when the main requirement is that the element exists in the DOM.
31. Presence vs Visibility
| Condition | Meaning |
| Presence | Element exists in the DOM. |
| Visibility | Element exists and is visible to the user. |
| Clickable | Element is suitable for clicking according to Selenium's condition. |
Choosing the appropriate wait condition is important for stable automation.
32. Handling Dynamic Buttons
Buttons may become enabled only after the user enters valid information.
WebDriverWait wait = new WebDriverWait(
driver,
Duration.ofSeconds(10)
);
WebElement submit = wait.until(
ExpectedConditions.elementToBeClickable(
By.id("submit")
)
);
submit.click();
33. Handling Dynamic Checkboxes
Checkboxes may be created dynamically or may have changing attributes.
WebElement checkbox = driver.findElement(
By.xpath("//label[normalize-space()='Subscribe']/input")
);
if (!checkbox.isSelected()) {
checkbox.click();
}
The script verifies the current state before changing it.
34. Handling Dynamic Radio Buttons
WebElement radio = driver.findElement(
By.xpath("//label[normalize-space()='Male']/input")
);
if (!radio.isSelected()) {
radio.click();
}
Checking the current state helps prevent unnecessary interactions.
35. Handling Dynamic Modals
Modern applications frequently display modal dialogs dynamically.
WebDriverWait wait = new WebDriverWait(
driver,
Duration.ofSeconds(10)
);
WebElement modal = wait.until(
ExpectedConditions.visibilityOfElementLocated(
By.cssSelector(".modal")
)
);
modal.findElement(
By.cssSelector(".close")
).click();
36. Handling Dynamic Popups
Dynamic popups may appear after login, navigation, scrolling, or user interaction.
A robust automation script should:
- Identify the popup reliably.
- Wait for its appearance when necessary.
- Perform the required action.
- Wait for it to disappear if it blocks the page.
37. Handling JavaScript Alerts
JavaScript alerts are browser dialogs and should be handled using Selenium's Alert API.
Alert alert = driver.switchTo().alert();
System.out.println(alert.getText());
alert.accept();
For dismissal:
driver.switchTo().alert().dismiss();
38. Handling Dynamic Iframes
Dynamic applications may create iframes after a user action.
WebDriverWait wait = new WebDriverWait(
driver,
Duration.ofSeconds(10)
);
wait.until(
ExpectedConditions.frameToBeAvailableAndSwitchToIt(
By.cssSelector("iframe.payment-frame")
)
);
After completing the interaction, return to the main document.
driver.switchTo().defaultContent();
39. Handling Dynamic Windows and Tabs
Applications may open a new window or tab dynamically.
String parentWindow = driver.getWindowHandle();
driver.findElement(By.id("openWindow")).click();
WebDriverWait wait = new WebDriverWait(
driver,
Duration.ofSeconds(10)
);
wait.until(
driver -> driver.getWindowHandles().size() > 1
);
for (String handle : driver.getWindowHandles()) {
if (!handle.equals(parentWindow)) {
driver.switchTo().window(handle);
break;
}
}
40. Handling Dynamic URLs
Some applications generate URLs containing IDs, tokens, or other dynamic values.
WebDriverWait wait = new WebDriverWait(
driver,
Duration.ofSeconds(10)
);
wait.until(
ExpectedConditions.urlContains("/dashboard")
);
Instead of validating the complete URL, the stable portion can be validated.
41. Handling Dynamic Page Titles
WebDriverWait wait = new WebDriverWait(
driver,
Duration.ofSeconds(10)
);
wait.until(
ExpectedConditions.titleContains("Dashboard")
);
42. Handling AJAX-Based Search Results
driver.findElement(By.id("search"))
.sendKeys("Laptop");
WebDriverWait wait = new WebDriverWait(
driver,
Duration.ofSeconds(10)
);
wait.until(
ExpectedConditions.visibilityOfElementLocated(
By.cssSelector(".search-results")
)
);
The automation waits for the result container instead of using a fixed delay.
43. Avoiding Thread.sleep()
Thread.sleep() pauses execution for a fixed amount of time.
Thread.sleep(5000);
Although it may appear simple, fixed sleeps can make tests slower and less reliable because the application may require either less or more time than the chosen duration.
Explicit waits are generally more suitable for dynamic conditions.
44. Thread.sleep() vs Explicit Wait
| Thread.sleep() | Explicit Wait |
| Fixed delay. | Condition-based waiting. |
| May unnecessarily slow tests. | Continues as soon as the condition is satisfied. |
| Does not understand application state. | Waits for a specific condition. |
| Less flexible. | More flexible. |
| Can make tests inefficient. | Usually better suited for dynamic applications. |
45. Handling Dynamic DOM Changes
The DOM can change after actions such as:
- Clicking a button.
- Submitting a form.
- Changing a dropdown.
- Searching for data.
- Opening a modal.
- Changing a filter.
- Refreshing a component.
- Receiving an API response.
Automation should locate elements as close as practical to the point of interaction and synchronize with the resulting state.
46. Handling Dynamic Element Attributes
Suppose the application generates:
<input id="input_12345" name="username">
The ID may change, but the name remains stable.
Use:
driver.findElement(
By.name("username")
).sendKeys("admin");
The stable attribute should be preferred over a volatile attribute.
47. Relative Locators
Selenium also provides relative locator capabilities that can help locate elements based on their relationship to other elements.
WebElement password = driver.findElement(
By.id("password")
);
WebElement username = driver.findElement(
with(By.tagName("input"))
.above(password)
);
Relative locators should be used when the relationship between elements is stable and improves readability.
48. Handling Dynamic Content with JavaScript
JavaScript can sometimes be useful for inspecting or interacting with dynamic application state, although normal Selenium interactions should generally be preferred when possible.
JavascriptExecutor js =
(JavascriptExecutor) driver;
String value = (String) js.executeScript(
"return document.title;"
);
System.out.println(value);
JavaScript should not be used as a replacement for proper synchronization or reliable Selenium interactions.
49. Scrolling to Dynamic Elements
WebElement element = driver.findElement(
By.id("checkout")
);
JavascriptExecutor js =
(JavascriptExecutor) driver;
js.executeScript(
"arguments[0].scrollIntoView({block:'center'});",
element
);
After scrolling, an explicit wait may be used when the element requires additional time to become interactive.
50. Handling Overlays
An overlay can cover an element and prevent Selenium from interacting with it.
Typical examples include:
- Cookie banners.
- Loading screens.
- Subscription popups.
- Modal dialogs.
- Chat widgets.
- Advertising overlays.
The automation should wait for the overlay to disappear or handle it explicitly.
wait.until(
ExpectedConditions.invisibilityOfElementLocated(
By.cssSelector(".overlay")
)
);
51. Handling ElementClickInterceptedException
ElementClickInterceptedException can occur when another element, such as an overlay, covers the element being clicked.
A robust approach is to determine why the element is blocked rather than immediately forcing a JavaScript click.
wait.until(
ExpectedConditions.invisibilityOfElementLocated(
By.cssSelector(".overlay")
)
);
wait.until(
ExpectedConditions.elementToBeClickable(
By.id("submit")
)
).click();
52. Handling NoSuchElementException
NoSuchElementException usually means Selenium could not locate the element using the supplied locator at that moment.
Possible reasons include:
- Incorrect locator.
- Element has not been created yet.
- Element is inside an iframe.
- Page navigation has not completed.
- DOM has changed.
- Application state is incorrect.
The solution should address the actual cause rather than simply adding a long delay.
53. Dynamic Web Elements in React Applications
React applications can frequently update portions of the DOM without a full page reload.
Automation challenges may include:
- Frequently re-rendered components.
- Changing element references.
- Dynamic classes.
- Asynchronous API responses.
- Virtualized lists.
Reliable attributes, appropriate waits, and fresh element lookup can help create more stable tests.
54. Dynamic Web Elements in Angular Applications
Angular applications can also update elements dynamically based on application state, API responses, and user interaction.
Selenium automation should focus on:
- Stable locators.
- Condition-based synchronization.
- Reliable page-state validation.
- Handling asynchronous content.
- Avoiding unnecessary fixed delays.
55. Dynamic Web Elements in Vue Applications
Vue applications can dynamically render and update components.
Common automation techniques remain the same:
- Use stable attributes.
- Use explicit waits.
- Re-locate stale elements.
- Validate application state.
- Avoid brittle XPath expressions.
56. Handling Virtualized Lists
Some modern applications render only the visible portion of a large list. These are called virtualized lists.
For example, an application may display 20 DOM elements even though the complete dataset contains thousands of records.
Automation may need to scroll the list and wait for the desired item to be rendered before locating it.
57. Dynamic Web Application Testing Strategy
Identify Dynamic Behavior
|
v
Find Stable Locator
|
v
Identify Synchronization Point
|
v
Choose Appropriate Wait
|
v
Perform Selenium Action
|
v
Validate Application State
|
v
Handle DOM Changes
|
v
Continue Test
58. Dynamic Locator Strategy
A practical locator priority can be:
- Unique and stable ID.
- Dedicated test attribute such as data-testid.
- Stable name or accessible attribute.
- Stable CSS selector.
- Relative XPath.
- Text-based locator when text is stable.
- Complex XPath only when necessary.
The goal is not to create the longest locator but the most stable and maintainable locator.
59. Dynamic Applications and Page Object Model
Dynamic application handling becomes easier to maintain when Selenium interactions are organized using the Page Object Model (POM).
Test Class
|
v
Page Object
|
+-- Stable Locators
|
+-- Explicit Waits
|
+-- Page Actions
|
v
Dynamic Application
Keeping dynamic-element logic inside page classes prevents the same locator and synchronization logic from being duplicated across multiple tests.
60. Dynamic Element Page Object Example
public class LoginPage {
private WebDriver driver;
private By username =
By.cssSelector("[data-testid='username']");
private By password =
By.cssSelector("[data-testid='password']");
private By loginButton =
By.cssSelector("[data-testid='login-button']");
private WebDriverWait wait;
public LoginPage(WebDriver driver) {
this.driver = driver;
this.wait = new WebDriverWait(
driver,
Duration.ofSeconds(10)
);
}
public void login(String user, String pass) {
wait.until(
ExpectedConditions.visibilityOfElementLocated(
username
)
).sendKeys(user);
driver.findElement(password)
.sendKeys(pass);
wait.until(
ExpectedConditions.elementToBeClickable(
loginButton
)
).click();
}
}
61. Dynamic Web Application with TestNG
@Test
public void loginTest() {
LoginPage loginPage =
new LoginPage(driver);
loginPage.login(
"admin",
"admin123"
);
Assert.assertTrue(
driver.getTitle().contains("Dashboard")
);
}
The test focuses on business behavior while the page class manages dynamic element synchronization.
62. Dynamic Application and Data-Driven Testing
Dynamic applications often require many input combinations. TestNG Data Providers can be combined with dynamic element handling.
@DataProvider(name = "users")
public Object[][] users() {
return new Object[][] {
{"admin", "admin123"},
{"manager", "manager123"},
{"employee", "employee123"}
};
}
@Test(dataProvider = "users")
public void loginTest(
String username,
String password) {
LoginPage page =
new LoginPage(driver);
page.login(username, password);
}
63. Dynamic Application and Screenshots
Screenshots are useful when dynamic application tests fail because they provide visual evidence of the application state at the time of failure.
File screenshot =
((TakesScreenshot) driver)
.getScreenshotAs(OutputType.FILE);
In a framework, screenshots can be captured automatically when a test fails.
64. Dynamic Application and Logging
Logging helps identify what happened before a dynamic application failure.
Useful information includes:
- Test name.
- Current URL.
- Locator being used.
- Expected condition.
- Input data.
- Browser.
- Exception details.
- Screenshot path.
65. Dynamic Application and Test Reports
Test reports should make it possible to identify whether a failure occurred because of a locator problem, synchronization issue, application defect, environment problem, or other cause.
A useful report can contain:
- Test case name.
- Pass/fail status.
- Execution duration.
- Browser information.
- Environment information.
- Failure message.
- Screenshot.
- Relevant logs.
66. Common Mistakes in Dynamic Web Application Automation
- Using unstable dynamically generated IDs.
- Using absolute XPath expressions unnecessarily.
- Using Thread.sleep() everywhere.
- Ignoring AJAX synchronization.
- Using one global WebDriver for parallel execution.
- Not handling stale elements.
- Ignoring loading overlays.
- Assuming an element is clickable simply because it exists.
- Using JavaScript clicks as the first solution to every problem.
- Not switching into the correct iframe.
- Not switching to the correct browser window.
- Using text that changes frequently as the primary locator.
- Not validating the application state after an action.
- Creating duplicated dynamic-element handling code.
67. Best Practices for Dynamic Web Applications
- Prefer stable and meaningful locators.
- Use dedicated test attributes when available.
- Use explicit waits for dynamic conditions.
- Avoid unnecessary fixed delays.
- Keep synchronization logic close to the relevant page action.
- Use Page Object Model for maintainability.
- Re-locate elements after known DOM replacements.
- Handle loading indicators and overlays.
- Use appropriate iframe and window switching.
- Keep test data separate from automation logic.
- Capture screenshots for failures.
- Use logging and reporting.
- Design WebDriver handling carefully for parallel execution.
- Keep locators simple, readable, and stable.
- Validate business outcomes rather than only checking that clicks occurred.
68. Dynamic Web Application Automation Checklist
| Check | Question |
| Locator | Is the locator stable? |
| Synchronization | Does the test wait for the correct condition? |
| DOM | Can the element be replaced dynamically? |
| AJAX | Does the test wait for asynchronous content? |
| Overlay | Can a popup or overlay block the element? |
| Frame | Is the element inside an iframe? |
| Window | Could the action open another window or tab? |
| State | Is the application in the expected state? |
| Failure Evidence | Are screenshots and logs available? |
| Maintainability | Is the logic reusable through Page Objects? |
69. Practical Project Structure
src
|-- test
|-- java
|-- tests
| |-- LoginTest.java
| |-- SearchTest.java
| |-- ProductTest.java
|
|-- pages
| |-- LoginPage.java
| |-- SearchPage.java
| |-- ProductPage.java
|
|-- utilities
| |-- DriverFactory.java
| |-- WaitUtils.java
| |-- ScreenshotUtils.java
| |-- ConfigReader.java
|
|-- data
| |-- TestDataProvider.java
|
|-- reports
|-- TestReport.html
70. Complete Practical Dynamic Web Application Example
The following example demonstrates a basic Selenium approach for interacting with dynamically loaded content.
import java.time.Duration;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.testng.Assert;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
public class DynamicApplicationTest {
private WebDriver driver;
private WebDriverWait wait;
@BeforeMethod
public void setup() {
driver = new ChromeDriver();
driver.manage().window().maximize();
wait = new WebDriverWait(
driver,
Duration.ofSeconds(15)
);
driver.get("https://example.com");
}
@Test
public void dynamicElementTest() {
WebElement search =
wait.until(
ExpectedConditions.visibilityOfElementLocated(
By.cssSelector("[data-testid='search']")
)
);
search.sendKeys("Selenium");
WebElement result =
wait.until(
ExpectedConditions.elementToBeClickable(
By.xpath(
"//div[contains(@class,'result') and contains(.,'Selenium')]"
)
)
);
result.click();
wait.until(
ExpectedConditions.titleContains("Selenium")
);
Assert.assertTrue(
driver.getTitle().contains("Selenium")
);
}
@AfterMethod
public void tearDown() {
if (driver != null) {
driver.quit();
}
}
}
71. Real-World E-Commerce Example
Consider an e-commerce application where products are loaded dynamically after a search.
Search Product
|
v
API Request
|
v
Products Loaded
|
v
Product Cards Created
|
v
Find Required Product
|
v
Wait for Add to Cart
|
v
Click Add to Cart
|
v
Cart Updated
|
v
Validate Cart
Selenium should wait for the relevant product and button instead of assuming that the product appears immediately after the search.
72. Real-World Dynamic Login Example
Open Login Page
|
v
Wait for Username
|
v
Enter Username
|
v
Enter Password
|
v
Wait for Login Button
|
v
Click Login
|
v
Wait for Dashboard
|
v
Validate Dashboard
This approach is more reliable than simply adding fixed delays between every step.
73. Dynamic Web Application Automation Architecture
Test Cases
|
v
Page Object Model
|
+---------+---------+
| |
v v
Stable Locators Wait Utilities
| |
+---------+---------+
|
v
Selenium WebDriver
|
v
Dynamic Web Application
|
+---------+---------+
| |
v v
AJAX/API JavaScript
| |
+---------+---------+
|
v
Updated DOM
|
v
Assertions
|
v
Reports
74. Dynamic Web Applications and CI/CD
Dynamic application automation should be designed to run reliably in CI/CD environments as well as local machines.
Developer Commit
|
v
Git Repository
|
v
CI/CD Pipeline
|
v
Build
|
v
Selenium Tests
|
v
Dynamic Application
|
v
Test Results
|
v
Reports + Screenshots
|
v
Build Result
Stable synchronization and reliable locators are particularly important in CI environments because execution speed and environment conditions may differ from a developer's local machine.
75. Dynamic Web Applications and Cross-Browser Testing
Dynamic behavior should be validated across supported browsers because rendering, timing, and browser behavior can sometimes differ.
| Browser | Example Validation |
| Chrome | Dynamic elements and AJAX content. |
| Firefox | Locator and synchronization behavior. |
| Edge | Dynamic forms and navigation. |
Cross-browser testing can be integrated with TestNG, Selenium Grid, or other execution infrastructure.
76. Dynamic Web Applications and Parallel Testing
When dynamic tests are executed in parallel, each test should have an isolated browser session and independent test data where required.
Test 1 ----> WebDriver 1 ----> Browser 1
Test 2 ----> WebDriver 2 ----> Browser 2
Test 3 ----> WebDriver 3 ----> Browser 3
Sharing a single mutable WebDriver instance between concurrent tests can result in unpredictable behavior.
77. Troubleshooting Dynamic Element Failures
| Problem | Possible Cause | Possible Solution |
| NoSuchElementException | Element not present yet. | Verify locator and use an appropriate wait. |
| StaleElementReferenceException | DOM element was replaced. | Locate the element again. |
| ElementClickInterceptedException | Overlay or another element blocks the click. | Handle overlay and wait for clickability. |
| TimeoutException | Condition not satisfied within timeout. | Verify locator, application state, and timeout. |
| ElementNotInteractableException | Element exists but cannot be interacted with. | Wait for visibility or appropriate state. |
| Wrong frame | Element is inside an iframe. | Switch to the required frame. |
| Wrong window | Element belongs to another tab/window. | Switch to the required window. |
78. Interview Questions on Dynamic Web Applications
1. What is a dynamic web application?
A dynamic web application is an application whose content, DOM, attributes, or behavior can change at runtime because of user actions, JavaScript, AJAX, APIs, server responses, or application state.
2. Why are dynamic applications difficult to automate?
They can contain changing locators, asynchronous content, dynamically generated elements, changing DOM structures, overlays, and timing-dependent behavior.
3. How do you handle dynamic IDs in Selenium?
Use stable attributes where possible or XPath functions such as contains() and starts-with() when appropriate.
4. How do you handle AJAX content?
Use condition-based explicit waits for the element or application state that indicates the AJAX operation has completed.
5. Why should Thread.sleep() generally be avoided?
It introduces a fixed delay rather than waiting for a meaningful application condition and can make tests slower or unreliable.
6. What is StaleElementReferenceException?
It occurs when a previously located WebElement is no longer attached to the current DOM.
7. How can StaleElementReferenceException be handled?
Re-locate the element after the DOM update and, where appropriate, use a limited retry strategy.
8. How do you handle dynamic dropdowns?
Wait for the dropdown options to appear or become clickable and then select the required option.
9. How do you handle dynamic tables?
Use stable table attributes and relative XPath or CSS selectors to identify the required row and its associated controls.
10. How do you handle loading spinners?
Wait for the spinner to disappear before interacting with elements that may be blocked by the loading state.
11. How do you handle dynamic popups?
Identify the popup, wait for its required state, interact with it, and wait for it to disappear when necessary.
12. How do you handle dynamic iframes?
Use an explicit wait for the frame and switch into it once it is available.
13. How do you handle dynamically generated browser tabs?
Store the original window handle, wait for the additional window, identify the new handle, and switch to it.
14. What is a stable locator?
A stable locator is a locator based on an attribute or relationship that is unlikely to change between executions.
15. What is the purpose of data-testid?
A data-testid attribute can provide a dedicated and stable hook for automated tests when the application team supports this practice.
16. Why is POM useful for dynamic applications?
POM keeps locators, waits, and page interactions in reusable page classes, reducing duplication in test cases.
17. Can dynamic applications be tested in parallel?
Yes, provided the automation framework is designed for thread safety and each test has appropriate isolation.
18. What causes ElementClickInterceptedException?
It can occur when another element, such as an overlay or popup, prevents the target element from receiving the click.
19. How do you handle dynamic URLs?
Validate stable portions of the URL using appropriate wait conditions instead of depending on a complete URL containing dynamic values.
20. What is the most important principle when automating dynamic applications?
The automation should synchronize with meaningful application conditions and use stable, maintainable locators instead of relying on fixed timing or brittle element paths.
79. Quick Reference Table
| Concept | Purpose |
| Dynamic Element | Element whose properties or DOM presence can change at runtime. |
| Stable Locator | Reliable way to identify an element. |
| Explicit Wait | Waits for a specific condition. |
| AJAX | Asynchronous communication that can update page content. |
| Stale Element | Previously located element that is no longer attached to the current DOM. |
| Dynamic XPath | XPath designed around stable portions of changing elements. |
| data-testid | Potential stable test hook. |
| Loading Spinner | Indicates asynchronous processing. |
| Overlay | Layer that can temporarily block page interaction. |
| Page Object Model | Separates page interaction logic from test logic. |
80. Learning Roadmap for Dynamic Web Applications
- Understand HTML and DOM structure.
- Learn Selenium WebDriver basics.
- Master Selenium locators.
- Learn XPath and CSS selectors.
- Understand dynamic IDs and attributes.
- Learn explicit waits.
- Understand AJAX and asynchronous behavior.
- Practice dynamic dropdowns and auto-suggestions.
- Practice dynamic tables.
- Handle loading indicators and overlays.
- Handle stale elements.
- Handle dynamic frames and windows.
- Practice infinite scroll and lazy-loaded content.
- Implement Page Object Model.
- Add screenshots and reporting.
- Build data-driven dynamic application tests.
- Run tests across multiple browsers.
- Integrate tests with CI/CD.
81. Practical Exercises
- Create a Selenium test for an application containing dynamic IDs.
- Create a dynamic XPath using contains().
- Create a dynamic XPath using starts-with().
- Automate an AJAX-based search box.
- Automate a dynamic dropdown.
- Automate an auto-suggestion search feature.
- Automate a dynamic table and locate a specific row.
- Click an action button inside a dynamic table row.
- Handle a loading spinner.
- Handle a dynamically displayed modal.
- Handle a dynamically generated iframe.
- Handle a new browser tab.
- Handle StaleElementReferenceException.
- Automate an infinite-scroll page.
- Build a Page Object Model for a dynamic application.
- Integrate dynamic tests with TestNG.
- Add screenshots for failed dynamic tests.
- Generate execution reports.
- Execute dynamic tests across multiple browsers.
- Run the framework through a CI/CD pipeline.
82. Summary
Dynamic web applications contain elements and content that can change during runtime because of JavaScript, AJAX, APIs, server responses, user actions, database data, and application state.
Selenium automation for dynamic applications requires reliable locators, appropriate synchronization, explicit waits, DOM awareness, and proper handling of changing elements.
Important techniques include dynamic XPath, stable CSS selectors, data-testid attributes, explicit waits, loading-spinner handling, AJAX synchronization, dynamic table handling, stale-element recovery, iframe switching, window handling, and overlay management.
For maintainable automation frameworks, these techniques should be combined with Page Object Model, reusable wait utilities, data-driven testing, screenshots, logging, reporting, cross-browser execution, and CI/CD integration.
Final Takeaway: The key to automating dynamic web applications is not simply waiting longer. The goal is to identify stable application conditions, locate elements reliably, synchronize with actual application state, and build reusable automation components that remain stable when the UI changes.
83. Course Resources
Learn more about Selenium automation testing and related framework concepts: